home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / X11R4 / cmds / X / ddx / mi / midispcur.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-15  |  17.0 KB  |  638 lines

  1. /*
  2.  * midispcur.c
  3.  *
  4.  * machine independent cursor display routines
  5.  */
  6.  
  7. /* $XConsortium: midispcur.c,v 5.9 89/08/30 19:23:59 keith Exp $ */
  8.  
  9. /*
  10. Copyright 1989 by the Massachusetts Institute of Technology
  11.  
  12. Permission to use, copy, modify, and distribute this software and its
  13. documentation for any purpose and without fee is hereby granted,
  14. provided that the above copyright notice appear in all copies and that
  15. both that copyright notice and this permission notice appear in
  16. supporting documentation, and that the name of M.I.T. not be used in
  17. advertising or publicity pertaining to distribution of the software
  18. without specific, written prior permission.  M.I.T. makes no
  19. representations about the suitability of this software for any
  20. purpose.  It is provided "as is" without express or implied warranty.
  21. */
  22.  
  23. #define NEED_EVENTS
  24. # include   "X.h"
  25. # include   "misc.h"
  26. # include   "input.h"
  27. # include   "cursorstr.h"
  28. # include   "windowstr.h"
  29. # include   "regionstr.h"
  30. # include   "dixstruct.h"
  31. # include   "scrnintstr.h"
  32. # include   "servermd.h"
  33. # include   "misprite.h"
  34. # include   "mipointer.h"
  35. # include   "gcstruct.h"
  36.  
  37. extern WindowPtr    *WindowTable;
  38.  
  39. /* per-screen private data */
  40.  
  41. static int    miDCScreenIndex;
  42. static unsigned long miDCGeneration = 0;
  43.  
  44. static Bool    miDCCloseScreen();
  45.  
  46. typedef struct {
  47.     GCPtr        pSourceGC, pMaskGC;
  48.     GCPtr        pSaveGC, pRestoreGC;
  49.     GCPtr        pMoveGC;
  50.     GCPtr        pPixSourceGC, pPixMaskGC;
  51.     Bool        (*CloseScreen)();
  52.     PixmapPtr        pSave, pTemp;
  53. } miDCScreenRec, *miDCScreenPtr;
  54.  
  55. /* per-cursor per-screen private data */
  56. typedef struct {
  57.     PixmapPtr        sourceBits;        /* source bits */
  58.     PixmapPtr        maskBits;        /* mask bits */
  59. } miDCCursorRec, *miDCCursorPtr;
  60.  
  61. /*
  62.  * sprite/cursor method table
  63.  */
  64.  
  65. static Bool    miDCRealizeCursor(),        miDCUnrealizeCursor();
  66. static Bool    miDCPutUpCursor(),        miDCSaveUnderCursor();
  67. static Bool    miDCRestoreUnderCursor(),   miDCMoveCursor();
  68. static Bool    miDCChangeSave();
  69.  
  70. static miSpriteCursorFuncRec miDCFuncs = {
  71.     miDCRealizeCursor,
  72.     miDCUnrealizeCursor,
  73.     miDCPutUpCursor,
  74.     miDCSaveUnderCursor,
  75.     miDCRestoreUnderCursor,
  76.     miDCMoveCursor,
  77.     miDCChangeSave,
  78. };
  79.  
  80. Bool
  81. miDCInitialize (pScreen, cursorFuncs)
  82.     ScreenPtr            pScreen;
  83.     miPointerCursorFuncPtr  cursorFuncs;
  84. {
  85.     miDCScreenPtr   pScreenPriv;
  86.  
  87.     if (miDCGeneration != serverGeneration)
  88.     {
  89.     miDCScreenIndex = AllocateScreenPrivateIndex ();
  90.     if (miDCScreenIndex < 0)
  91.         return FALSE;
  92.     miDCGeneration = serverGeneration;
  93.     }
  94.     pScreenPriv = (miDCScreenPtr) xalloc (sizeof (miDCScreenRec));
  95.     if (!pScreenPriv)
  96.     return FALSE;
  97.  
  98.     /*
  99.      * initialize the entire private structure to zeros
  100.      */
  101.  
  102.     pScreenPriv->pSourceGC =
  103.     pScreenPriv->pMaskGC =
  104.     pScreenPriv->pSaveGC =
  105.      pScreenPriv->pRestoreGC =
  106.      pScreenPriv->pMoveGC =
  107.      pScreenPriv->pPixSourceGC =
  108.     pScreenPriv->pPixMaskGC = NULL;
  109.     
  110.     pScreenPriv->pSave = pScreenPriv->pTemp = NULL;
  111.  
  112.     pScreenPriv->CloseScreen = pScreen->CloseScreen;
  113.     pScreen->CloseScreen = miDCCloseScreen;
  114.     
  115.     pScreen->devPrivates[miDCScreenIndex].ptr = (pointer) pScreenPriv;
  116.  
  117.     if (!miSpriteInitialize (pScreen, &miDCFuncs, cursorFuncs))
  118.     {
  119.     xfree ((pointer) pScreenPriv);
  120.     return FALSE;
  121.     }
  122.     return TRUE;
  123. }
  124.  
  125. #define tossGC(gc)  (gc ? FreeGC (gc, (GContext) 0) : 0)
  126. #define tossPix(pix)    (pix ? (*pScreen->DestroyPixmap) (pix) : TRUE)
  127.  
  128. static Bool
  129. miDCCloseScreen (index, pScreen)
  130.     ScreenPtr    pScreen;
  131. {
  132.     miDCScreenPtr   pScreenPriv;
  133.  
  134.     pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
  135.     pScreen->CloseScreen = pScreenPriv->CloseScreen;
  136.     tossGC (pScreenPriv->pSourceGC);
  137.     tossGC (pScreenPriv->pMaskGC);
  138.     tossGC (pScreenPriv->pSaveGC);
  139.     tossGC (pScreenPriv->pRestoreGC);
  140.     tossGC (pScreenPriv->pMoveGC);
  141.     tossGC (pScreenPriv->pPixSourceGC);
  142.     tossGC (pScreenPriv->pPixMaskGC);
  143.     tossPix (pScreenPriv->pSave);
  144.     tossPix (pScreenPriv->pTemp);
  145.     xfree ((pointer) pScreenPriv);
  146.     return (*pScreen->CloseScreen) (index, pScreen);
  147. }
  148.  
  149. static Bool
  150. miDCRealizeCursor (pScreen, pCursor)
  151.     ScreenPtr    pScreen;
  152.     CursorPtr    pCursor;
  153. {
  154.     if (pCursor->bits->refcnt <= 1)
  155.     pCursor->bits->devPriv[pScreen->myNum] = (pointer)NULL;
  156.     return TRUE;
  157. }
  158.  
  159. static miDCCursorPtr
  160. miDCRealize (pScreen, pCursor)
  161.     ScreenPtr    pScreen;
  162.     CursorPtr    pCursor;
  163. {
  164.     miDCCursorPtr   pPriv;
  165.     GCPtr        pGC;
  166.     XID            gcvals[3];
  167.  
  168.     pPriv = (miDCCursorPtr) xalloc (sizeof (miDCCursorRec));
  169.     if (!pPriv)
  170.     return (miDCCursorPtr)NULL;
  171.     pPriv->sourceBits = (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1);
  172.     if (!pPriv->sourceBits)
  173.     {
  174.     xfree ((pointer) pPriv);
  175.     return (miDCCursorPtr)NULL;
  176.     }
  177.     pPriv->maskBits =  (*pScreen->CreatePixmap) (pScreen, pCursor->bits->width, pCursor->bits->height, 1);
  178.     if (!pPriv->maskBits)
  179.     {
  180.     (*pScreen->DestroyPixmap) (pPriv->sourceBits);
  181.     xfree ((pointer) pPriv);
  182.     return (miDCCursorPtr)NULL;
  183.     }
  184.     pCursor->bits->devPriv[pScreen->myNum] = (pointer) pPriv;
  185.  
  186.     /* create the two sets of bits, clipping as appropriate */
  187.  
  188.     pGC = GetScratchGC (1, pScreen);
  189.     if (!pGC)
  190.     {
  191.     (void) miDCUnrealizeCursor (pScreen, pCursor);
  192.     return (miDCCursorPtr)NULL;
  193.     }
  194.  
  195.     ValidateGC ((DrawablePtr)pPriv->sourceBits, pGC);
  196.     (*pGC->ops->PutImage) (pPriv->sourceBits, pGC, 1,
  197.                0, 0, pCursor->bits->width, pCursor->bits->height,
  198.                 0, XYPixmap, pCursor->bits->source);
  199.     gcvals[0] = GXand;
  200.     ChangeGC (pGC, GCFunction, gcvals);
  201.     ValidateGC ((DrawablePtr)pPriv->sourceBits, pGC);
  202.     (*pGC->ops->PutImage) (pPriv->sourceBits, pGC, 1,
  203.                0, 0, pCursor->bits->width, pCursor->bits->height,
  204.                 0, XYPixmap, pCursor->bits->mask);
  205.  
  206.     /* mask bits -- pCursor->mask & ~pCursor->source */
  207.     gcvals[0] = GXcopy;
  208.     ChangeGC (pGC, GCFunction, gcvals);
  209.     ValidateGC ((DrawablePtr)pPriv->maskBits, pGC);
  210.     (*pGC->ops->PutImage) (pPriv->maskBits, pGC, 1,
  211.                0, 0, pCursor->bits->width, pCursor->bits->height,
  212.                 0, XYPixmap, pCursor->bits->mask);
  213.     gcvals[0] = GXandInverted;
  214.     ChangeGC (pGC, GCFunction, gcvals);
  215.     ValidateGC ((DrawablePtr)pPriv->maskBits, pGC);
  216.     (*pGC->ops->PutImage) (pPriv->maskBits, pGC, 1,
  217.                0, 0, pCursor->bits->width, pCursor->bits->height,
  218.                 0, XYPixmap, pCursor->bits->source);
  219.     FreeScratchGC (pGC);
  220.     return pPriv;
  221. }
  222.  
  223. static Bool
  224. miDCUnrealizeCursor (pScreen, pCursor)
  225.     ScreenPtr    pScreen;
  226.     CursorPtr    pCursor;
  227. {
  228.     miDCCursorPtr   pPriv;
  229.  
  230.     pPriv = (miDCCursorPtr) pCursor->bits->devPriv[pScreen->myNum];
  231.     if (pPriv && (pCursor->bits->refcnt <= 1))
  232.     {
  233.     (*pScreen->DestroyPixmap) (pPriv->sourceBits);
  234.     (*pScreen->DestroyPixmap) (pPriv->maskBits);
  235.     xfree ((pointer) pPriv);
  236.     pCursor->bits->devPriv[pScreen->myNum] = (pointer)NULL;
  237.     }
  238.     return TRUE;
  239. }
  240.  
  241. static void
  242. miDCPutBits (pDrawable, pPriv, sourceGC, maskGC, x, y, w, h, source, mask)
  243.     DrawablePtr        pDrawable;
  244.     GCPtr        sourceGC, maskGC;
  245.     int             x, y;
  246.     unsigned        w, h;
  247.     miDCCursorPtr   pPriv;
  248.     unsigned long   source, mask;
  249. {
  250.     XID        gcvals[1];
  251.  
  252.     if (sourceGC->fgPixel != source)
  253.     {
  254.     gcvals[0] = source;
  255.     DoChangeGC (sourceGC, GCForeground, gcvals, 0);
  256.     }
  257.     if (sourceGC->serialNumber != pDrawable->serialNumber)
  258.     ValidateGC (pDrawable, sourceGC);
  259.     (*sourceGC->ops->PushPixels) (sourceGC, pPriv->sourceBits, pDrawable, w, h, x, y);
  260.     if (maskGC->fgPixel != mask)
  261.     {
  262.     gcvals[0] = mask;
  263.     DoChangeGC (maskGC, GCForeground, gcvals, 0);
  264.     }
  265.     if (maskGC->serialNumber != pDrawable->serialNumber)
  266.     ValidateGC (pDrawable, maskGC);
  267.     (*maskGC->ops->PushPixels) (maskGC, pPriv->maskBits, pDrawable, w, h, x, y);
  268. }
  269.  
  270. static Bool
  271. miDCPutUpCursor (pScreen, pCursor, x, y, source, mask)
  272.     ScreenPtr        pScreen;
  273.     CursorPtr        pCursor;
  274.     unsigned long   source, mask;
  275. {
  276.     miDCScreenPtr   pScreenPriv;
  277.     miDCCursorPtr   pPriv;
  278.     WindowPtr        pWin;
  279.     int            status;
  280.     XID            gcvals[2];
  281.  
  282.     pPriv = (miDCCursorPtr) pCursor->bits->devPriv[pScreen->myNum];
  283.     if (!pPriv)
  284.     {
  285.     pPriv = miDCRealize(pScreen, pCursor);
  286.     if (!pPriv)
  287.         return FALSE;
  288.     }
  289.     pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
  290.     pWin = WindowTable[pScreen->myNum];
  291.     if (!pScreenPriv->pSourceGC)
  292.     {
  293.     gcvals[0] = IncludeInferiors;
  294.     gcvals[1] = FALSE;
  295.     pScreenPriv->pSourceGC = CreateGC((DrawablePtr)pWin,
  296.         GCSubwindowMode|GCGraphicsExposures, gcvals, &status);
  297.     if (!pScreenPriv->pSourceGC)
  298.         return FALSE;
  299.     pScreenPriv->pMaskGC = CreateGC((DrawablePtr)pWin,
  300.         GCSubwindowMode|GCGraphicsExposures, gcvals, &status);
  301.     if (!pScreenPriv->pMaskGC)
  302.     {
  303.         FreeGC (pScreenPriv->pSourceGC, (GContext) 0);
  304.         pScreenPriv->pSourceGC = 0;
  305.         return FALSE;
  306.     }
  307.     }
  308.     miDCPutBits ((DrawablePtr)pWin, pPriv,
  309.          pScreenPriv->pSourceGC, pScreenPriv->pMaskGC,
  310.          x, y, pCursor->bits->width, pCursor->bits->height,
  311.          source, mask);
  312.     return TRUE;
  313. }
  314.  
  315. static Bool
  316. miDCSaveUnderCursor (pScreen, x, y, w, h)
  317.     ScreenPtr    pScreen;
  318.     int        x, y, w, h;
  319. {
  320.     miDCScreenPtr   pScreenPriv;
  321.     PixmapPtr        pSave;
  322.     WindowPtr        pWin;
  323.     GCPtr        pGC;
  324.     XID            gcvals[2];
  325.     int            status;
  326.  
  327.     pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
  328.     pSave = pScreenPriv->pSave;
  329.     pWin = WindowTable[pScreen->myNum];
  330.     if (!pSave || pSave->drawable.width < w || pSave->drawable.height < h)
  331.     {
  332.     if (pSave)
  333.         (*pScreen->DestroyPixmap) (pSave);
  334.     pScreenPriv->pSave = pSave =
  335.         (*pScreen->CreatePixmap) (pScreen, w, h, pScreen->rootDepth);
  336.     if (!pSave)
  337.         return FALSE;
  338.     }
  339.     if (!pScreenPriv->pSaveGC)
  340.     {
  341.     gcvals[0] = IncludeInferiors;
  342.     gcvals[1] = FALSE;
  343.     pScreenPriv->pSaveGC = CreateGC ((DrawablePtr)pWin,
  344.         GCSubwindowMode|GCGraphicsExposures, gcvals, &status);
  345.     if (!pScreenPriv->pSaveGC)
  346.         return FALSE;
  347.     }
  348.     pGC = pScreenPriv->pSaveGC;
  349.     if (pSave->drawable.serialNumber != pGC->serialNumber)
  350.     ValidateGC ((DrawablePtr) pSave, pGC);
  351.     (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
  352.                 x, y, w, h, 0, 0);
  353.     return TRUE;
  354. }
  355.  
  356. static Bool
  357. miDCRestoreUnderCursor (pScreen, x, y, w, h)
  358.     ScreenPtr    pScreen;
  359.     int        x, y, w, h;
  360. {
  361.     miDCScreenPtr   pScreenPriv;
  362.     PixmapPtr        pSave;
  363.     WindowPtr        pWin;
  364.     GCPtr        pGC;
  365.     XID            gcvals[2];
  366.     int            status;
  367.  
  368.     pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
  369.     pSave = pScreenPriv->pSave;
  370.     pWin = WindowTable[pScreen->myNum];
  371.     if (!pSave)
  372.     return FALSE;
  373.     if (!pScreenPriv->pRestoreGC)
  374.     {
  375.     gcvals[0] = IncludeInferiors;
  376.     gcvals[1] = FALSE;
  377.     pScreenPriv->pRestoreGC = CreateGC ((DrawablePtr)pWin,
  378.         GCSubwindowMode|GCGraphicsExposures, gcvals, &status);
  379.     if (!pScreenPriv->pRestoreGC)
  380.         return FALSE;
  381.     }
  382.     pGC = pScreenPriv->pRestoreGC;
  383.     if (pWin->drawable.serialNumber != pGC->serialNumber)
  384.     ValidateGC ((DrawablePtr) pWin, pGC);
  385.     (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
  386.                 0, 0, w, h, x, y);
  387.     return TRUE;
  388. }
  389.  
  390. static Bool
  391. miDCChangeSave (pScreen, x, y, w, h, dx, dy)
  392.     ScreenPtr        pScreen;
  393. {
  394.     miDCScreenPtr   pScreenPriv;
  395.     PixmapPtr        pSave;
  396.     WindowPtr        pWin;
  397.     GCPtr        pGC;
  398.     XID            gcvals[2];
  399.     int            status;
  400.     int            sourcex, sourcey, destx, desty, copyw, copyh;
  401.  
  402.     pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
  403.     pSave = pScreenPriv->pSave;
  404.     pWin = WindowTable[pScreen->myNum];
  405.     /*
  406.      * restore the bits which are about to get trashed
  407.      */
  408.     if (!pSave)
  409.     return FALSE;
  410.     if (!pScreenPriv->pRestoreGC)
  411.     {
  412.     gcvals[0] = IncludeInferiors;
  413.     gcvals[1] = FALSE;
  414.     pScreenPriv->pRestoreGC = CreateGC ((DrawablePtr)pWin,
  415.         GCSubwindowMode|GCGraphicsExposures, gcvals, &status);
  416.     if (!pScreenPriv->pRestoreGC)
  417.         return FALSE;
  418.     }
  419.     pGC = pScreenPriv->pRestoreGC;
  420.     if (pWin->drawable.serialNumber != pGC->serialNumber)
  421.     ValidateGC ((DrawablePtr) pWin, pGC);
  422.     /*
  423.      * copy the old bits to the screen.
  424.      */
  425.     if (dy > 0)
  426.     {
  427.     (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
  428.                    0, h - dy, w, dy, x + dx, y + h);
  429.     }
  430.     else if (dy < 0)
  431.     {
  432.     (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
  433.                    0, 0, w, -dy, x + dx, y + dy);
  434.     }
  435.     if (dy >= 0)
  436.     {
  437.     desty = y + dy;
  438.     sourcey = 0;
  439.     copyh = h - dy;
  440.     }
  441.     else
  442.     {
  443.     desty = y;
  444.     sourcey = - dy;
  445.     copyh = h + dy;
  446.     }
  447.     if (dx > 0)
  448.     {
  449.     (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
  450.                    w - dx, sourcey, dx, copyh, x + w, desty);
  451.     }
  452.     else if (dx < 0)
  453.     {
  454.     (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pWin, pGC,
  455.                    0, sourcey, -dx, copyh, x + dx, desty);
  456.     }
  457.     if (!pScreenPriv->pSaveGC)
  458.     {
  459.     gcvals[0] = IncludeInferiors;
  460.     gcvals[1] = FALSE;
  461.     pScreenPriv->pSaveGC = CreateGC ((DrawablePtr)pWin,
  462.         GCSubwindowMode|GCGraphicsExposures, gcvals, &status);
  463.     if (!pScreenPriv->pSaveGC)
  464.         return FALSE;
  465.     }
  466.     pGC = pScreenPriv->pSaveGC;
  467.     if (pSave->drawable.serialNumber != pGC->serialNumber)
  468.     ValidateGC ((DrawablePtr) pSave, pGC);
  469.     /*
  470.      * move the bits that are still valid within the pixmap
  471.      */
  472.     if (dx >= 0)
  473.     {
  474.     sourcex = 0;
  475.     destx = dx;
  476.     copyw = w - dx;
  477.     }
  478.     else
  479.     {
  480.     destx = 0;
  481.     sourcex = - dx;
  482.     copyw = w + dx;
  483.     }
  484.     if (dy >= 0)
  485.     {
  486.     sourcey = 0;
  487.     desty = dy;
  488.     copyh = h - dy;
  489.     }
  490.     else
  491.     {
  492.     desty = 0;
  493.     sourcey = -dy;
  494.     copyh = h + dy;
  495.     }
  496.     (*pGC->ops->CopyArea) ((DrawablePtr) pSave, (DrawablePtr) pSave, pGC,
  497.                sourcex, sourcey, copyw, copyh, destx, desty);
  498.     /*
  499.      * copy the new bits from the screen into the remaining areas of the
  500.      * pixmap
  501.      */
  502.     if (dy > 0)
  503.     {
  504.     (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
  505.                    x, y, w, dy, 0, 0);
  506.     }
  507.     else if (dy < 0)
  508.     {
  509.     (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
  510.                    x, y + h + dy, w, -dy, 0, h + dy);
  511.     }
  512.     if (dy >= 0)
  513.     {
  514.     desty = dy;
  515.     sourcey = y + dy;
  516.     copyh = h - dy;
  517.     }
  518.     else
  519.     {
  520.     desty = 0;
  521.     sourcey = y;
  522.     copyh = h + dy;
  523.     }
  524.     if (dx > 0)
  525.     {
  526.     (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
  527.                    x, sourcey, dx, copyh, 0, desty);
  528.     }
  529.     else if (dx < 0)
  530.     {
  531.     (*pGC->ops->CopyArea) ((DrawablePtr) pWin, (DrawablePtr) pSave, pGC,
  532.                    x + w + dx, sourcey, -dx, copyh, w + dx, desty);
  533.     }
  534.     return TRUE;
  535. }
  536.  
  537. static Bool
  538. miDCMoveCursor (pScreen, pCursor, x, y, w, h, dx, dy, source, mask)
  539.     ScreenPtr        pScreen;
  540.     CursorPtr        pCursor;
  541.     unsigned long   source, mask;
  542. {
  543.     miDCCursorPtr   pPriv;
  544.     miDCScreenPtr   pScreenPriv;
  545.     int            status;
  546.     WindowPtr        pWin;
  547.     GCPtr        pGC;
  548.     XID            gcvals[2];
  549.     PixmapPtr        pTemp;
  550.  
  551.     pPriv = (miDCCursorPtr) pCursor->bits->devPriv[pScreen->myNum];
  552.     if (!pPriv)
  553.     {
  554.     pPriv = miDCRealize(pScreen, pCursor);
  555.     if (!pPriv)
  556.         return FALSE;
  557.     }
  558.     pScreenPriv = (miDCScreenPtr) pScreen->devPrivates[miDCScreenIndex].ptr;
  559.     pWin = WindowTable[pScreen->myNum];
  560.     pTemp = pScreenPriv->pTemp;
  561.     if (!pTemp ||
  562.     pTemp->drawable.width != pScreenPriv->pSave->drawable.width ||
  563.     pTemp->drawable.height != pScreenPriv->pSave->drawable.height)
  564.     {
  565.     if (pTemp)
  566.         (*pScreen->DestroyPixmap) (pTemp);
  567.     pScreenPriv->pTemp = pTemp = (*pScreen->CreatePixmap)
  568.         (pScreen, w, h, pScreenPriv->pSave->drawable.depth);
  569.     if (!pTemp)
  570.         return FALSE;
  571.     }
  572.     if (!pScreenPriv->pMoveGC)
  573.     {
  574.     gcvals[0] = IncludeInferiors;
  575.     gcvals[1] = FALSE;
  576.     pScreenPriv->pMoveGC = CreateGC ((DrawablePtr)pTemp,
  577.         GCSubwindowMode|GCGraphicsExposures, gcvals, &status);
  578.     if (!pScreenPriv->pMoveGC)
  579.         return FALSE;
  580.     }
  581.     /*
  582.      * copy the saved area to a temporary pixmap
  583.      */
  584.     pGC = pScreenPriv->pMoveGC;
  585.     if (pGC->serialNumber != pTemp->drawable.serialNumber)
  586.     ValidateGC ((DrawablePtr) pTemp, pGC);
  587.     (*pGC->ops->CopyArea)
  588.     (pScreenPriv->pSave, pTemp, pGC, 0, 0, w, h, 0, 0);
  589.     
  590.     /*
  591.      * draw the cursor in the temporary pixmap
  592.      */
  593.     if (!pScreenPriv->pPixSourceGC)
  594.     {
  595.     gcvals[0] = IncludeInferiors;
  596.     gcvals[1] = FALSE;
  597.     pScreenPriv->pPixSourceGC = CreateGC ((DrawablePtr)pTemp,
  598.         GCSubwindowMode|GCGraphicsExposures, gcvals, &status);
  599.     if (!pScreenPriv->pPixSourceGC)
  600.         return FALSE;
  601.     }
  602.     if (!pScreenPriv->pPixMaskGC)
  603.     {
  604.     gcvals[0] = IncludeInferiors;
  605.     gcvals[1] = FALSE;
  606.     pScreenPriv->pPixMaskGC = CreateGC ((DrawablePtr)pTemp,
  607.         GCSubwindowMode|GCGraphicsExposures, gcvals, &status);
  608.     if (!pScreenPriv->pPixMaskGC)
  609.         return FALSE;
  610.     }
  611.     miDCPutBits ((DrawablePtr)pTemp, pPriv,
  612.          pScreenPriv->pPixSourceGC, pScreenPriv->pPixMaskGC,
  613.           dx, dy, pCursor->bits->width, pCursor->bits->height,
  614.          source, mask);
  615.  
  616.     /*
  617.      * copy the temporary pixmap onto the screen
  618.      */
  619.  
  620.     if (!pScreenPriv->pRestoreGC)
  621.     {
  622.     gcvals[0] = IncludeInferiors;
  623.     gcvals[1] = FALSE;
  624.     pScreenPriv->pRestoreGC = CreateGC ((DrawablePtr)pWin,
  625.         GCSubwindowMode|GCGraphicsExposures, gcvals, &status);
  626.     if (!pScreenPriv->pRestoreGC)
  627.         return FALSE;
  628.     }
  629.     pGC = pScreenPriv->pRestoreGC;
  630.     if (pWin->drawable.serialNumber != pGC->serialNumber)
  631.     ValidateGC ((DrawablePtr) pWin, pGC);
  632.  
  633.     (*pGC->ops->CopyArea) ((DrawablePtr) pTemp, (DrawablePtr) pWin,
  634.                 pGC,
  635.                 0, 0, w, h, x, y);
  636.     return TRUE;
  637. }
  638.